//
// Created by yuping.li on 10/28/24.
//

#ifndef DISPLAY_TASK_HPP_
#define DISPLAY_TASK_HPP_

#include "task.hpp"
#include "oled/zjy_oled_driver.hpp"
#include "i2c.h"
#include "rte/rte.hpp"
#include "incubator/state_machine/fsm_incubatorfsm.h"

class DisplayTask : public Task {
 public:
  DisplayTask() {
    period_ms = 500U;
  }
  void init_task() override {
    oled = std::make_unique<ZjyOledDriver>(&hi2c2, 0x78);
    oled->init();
    oled->clear();
  }
  void period_task() override {
    handler[Rte::instance().incubator_mode]();
  }

 protected:
  std::unique_ptr<ZjyOledDriver> oled{nullptr};
  std::map<uint32_t, std::function<void()>> handler {
      {MODE_STANDBY, [this]{standby();}},
      {MODE_CUSTOMER, [this]{customer();}},
      {MODE_WORKING, [this]{working();}},
      {MODE_PARROT, [this]{parrot();}},
      {MODE_EGG, [this]{egg();}},

  };

  void standby() {
    static char t[16]{};
    oled->clear();
    sprintf(t, "a:%.1f h:%.1f", Rte::instance().current_temp/10.0, Rte::instance().heater_temp/10.0);
    oled->write_string_to_buffer(0, 0, Rte::instance().incubator_mode_name.c_str());
    oled->write_string_to_buffer(0, 2, t);
    oled->flush_buffer();
  }

  void customer() {
    static char t[16]{};
    oled->clear();
    sprintf(t, "target: %.1f", Rte::instance().target_temp/10.0);
    oled->write_string_to_buffer(0, 0, Rte::instance().incubator_mode_name.c_str());
    oled->write_string_to_buffer(0, 2, t);
    oled->flush_buffer();
  }

  void working() {
    static char t[16]{};
    oled->clear();
    oled->write_string_to_buffer(0, 0, Rte::instance().incubator_mode_name.c_str());
    sprintf(t, "target: %.1f", Rte::instance().target_temp/10.0);
    oled->write_string_to_buffer(0, 2, t);
    sprintf(t, "a %.1f h %.1f", Rte::instance().current_temp/10.0, Rte::instance().heater_temp/10.0);
    oled->write_string_to_buffer(0, 4, t);
    sprintf(t, "f: %lu h %lu", Rte::instance().fan_duty, Rte::instance().heater_duty);
    oled->write_string_to_buffer(0, 6, t);
    oled->flush_buffer();
  }

  void egg() {
    oled->clear();
    oled->write_string_to_buffer(0, 0, Rte::instance().incubator_mode_name.c_str());
    oled->flush_buffer();
  }

  void parrot() {
    oled->clear();
    oled->write_string_to_buffer(0, 0, Rte::instance().incubator_mode_name.c_str());
    oled->flush_buffer();
  }
};

#endif //DISPLAY_TASK_HPP_
